<?php
/**
 * Form elements for Bureaucracy Plugin Helper
 *
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Andreas Gohr <andi@splitbrain.org>
 * @author     Stephane Chamberland <dokuwiki@meteokid.ca>
 * @date       2009-08-01
 */

// must be run within Dokuwiki
if (!defined('DOKU_INC')) die();

/**
 *
 */
class helper_plugin_bureaucracy2_element {

    public $label = '';
    public $id = '';
    public $error = false;

    protected $name = ''; //name/type of the element
    protected $args_min = 0;
    protected $args_max = 9;
    protected $opt = array();
    protected $class = '';

    protected $classes = array(
            'optional' => 'bureaucracy_optional',
            'required' => 'bureaucracy_required',
            'error'    => 'bureaucracy_error'
            );


    function __construct() {
        $this->name = substr(get_class($this),strlen('helper_plugin_bureaucracy2_element'));
        msg('Name:'.$this->name,0);
    }
    
    //==== 1- parse elm desc
    /**
     * Parse From Def args - call msg(..,-1) on error
     * @input $args: array - list of elements args
     * @input $id: string - default element id
     * @return bool - true on error
     */
    public function parse_args($args,$id=0){
        //$this->name = $args[0];
        //array_shift($args);
        $this->label = $args[0];
        array_shift($args);
        $this->id = $id;
        $this->class = $this->classes['required'];
        $err = $this->parse_args_special($args);
        //TODO: return error if any
        foreach($args as $arg){
            if($arg[0] == '='){
                $opt['default'] = substr($arg,1);
            }elseif($arg[0] == '>'){
                $opt['min'] = $this->check_gt_lt(substr($arg,1));
                if(!$opt['min']) unset($opt['min']);
                //TODO: error msg
            }elseif($arg[0] == '<'){
                $opt['max'] = $this->check_gt_lt(substr($arg,1));
                if(!$opt['max']) unset($opt['max']);
                //TODO: error msg
            }elseif($arg[0] == '/' && substr($arg,-1) == '/'){
                $opt['re'] = substr($arg,1,-1);
            }elseif($arg == '!'){
                $opt['optional'] = true;
                $this->class = $this->classes['optional'];
            }elseif($arg[0] == '#'){
                $opt['maxlen'] = substr($arg,1); //SCH: optional max char of input len
                if(!is_numeric($opt['maxlen'])) unset($opt['maxlen']);
                //TODO: error msg
            }elseif($arg[0] == '&'){
                $this->id = cleanID(substr($arg,1),false,true); //SCH: optional element name
            //}elseif($arg == '@'){
            //    $opt['pagename'] = true;
            }elseif(preg_match('/x\d/', $arg)) {
                $opt['rows'] = substr($arg,1);
            }
        }
        return false; //TODO: true if error
    }

    /**
     * Pre-Parse From Def args
     * call at the beginning of parse_args() to modify args or parse special args
     * - Can be implemented in derived class
     */
    protected function parse_args_special(&$args){
        return ''; //Should return errors
    }

    //==== 2- display elm html or simply add it to the form object

    /**
     * Add the html form element to the form object
     * @input ...
     * @return ...
     * - Needs to be implemented in derived class
     */
    public function htmlform_elm(&$form,$values=NULL,$errors=NULL,$reset=false){
        return;
    }

    //==== 3- get/check elm posted value [$GET/$POST... ?? $SESSION/$COOKIE

    /**
     *
     */
    public function get_value($values=NULL,$reset=false){
        $value = '';
        if(!$reset && isset($values[$this->id])){
            $value = $values[$this->id];
        }else{
            $value = $opt['default'];
        }
        if(isset($opt['maxlen'])) $value = substr(trim(cleanText($value)),0,$opt['maxlen']);
        return $values;
    }

    /**
     * Check if posted value is valid - call msg(..,-1) on error
     * @input $values: array -
     * @return string - element id on error (false otherwise)
     * - Needs to be implemented in derived class
     */
    public function checkpost($values=NULL){
        //TODO: check basic conditions: min/max lenght, optional...
        //check $values[$this->id]
        //Need to set $this->error on error
        return false; //return err msg on error
    }


    /**
     * Clean posted values from potential malicious code
     */
    public function clean_value($value){
        //TODO: see links below
        //http://micropipes.com/blog/2009/02/23/how-addonsmozillaorg-defends-against-xss-attacks/
        //http://svn.mozilla.org/addons/trunk/site/cake/libs/sanitize.php
        return $value;
    }


    /**
     * Validate ">" and "<" From Def args
     */
    protected function check_gt_lt($arg){
        if(is_numeric($arg)) return $arg;
        return '';
    }

}

/**
 *
 */
class helper_plugin_bureaucracy2_element_textbox extends helper_plugin_bureaucracy2_element {

    protected $args_min = 2;
    protected $args_max = 9;

    /**
     * Add the html form element to the form object
     */
    public function htmlform_elm(&$form,$form_pefix,$values=NULL,$reset=false){
        $name = $form_prefix.'['.$this->id.']';

        $value = $this->get_value($values,$reset);

        $class = $this->class;
        if($this->error)$class .= " ".$this->classes['error'];

        $form->addElement(form_makeTextField($name,$value,$this->label,'',$class));
        return;
    }

    /**
     * Check if posted value is valid - call msg(..,-1) on error
     * @input $values: array -
     * @return string - element id on error (false otherwise)
     */
    public function checkpost($values=NULL){
        //check $values[$this->id]
        //Need to set $this->error on error
        return false; //return err msg on error
    }

}
